package pwd.allen.simple;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;
import pwd.allen.simple.handler.ChatClientHandler;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.Scanner;

/**
 * @author 门那粒沙
 * @create 2019-10-27 18:18
 **/
public class NettyClient {

    public static Charset charset = CharsetUtil.UTF_8;
//    public static Charset charset = Charset.forName("GBK");

    private String host;
    private int port;

    public NettyClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void run() {
        //创建一个事件循环组
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();

        try {
            //创建客户端的启动对象，配置参数
            Bootstrap bootstrap = new Bootstrap();

            //使用链式编程来进行设置
            bootstrap.group(eventLoopGroup)//设置线程组
                    .channel(NioSocketChannel.class)//设置客户端的通道实现（反射）
                    .handler(new ChannelInitializer<SocketChannel>() {//创建一个通道初始化对象
                        /**
                         * 给pipeline设置处理器
                         * @param socketChannel
                         * @throws Exception
                         */
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            pipeline.addLast("decoder", new StringDecoder(charset));
                            pipeline.addLast("encoder", new StringEncoder(charset));
                            pipeline.addLast("chat", new ChatClientHandler());
                        }
                    });//给WorkerGroup的EventLoop对应的管道设置处理器


            //启动客户器并绑定端口，并且异步（方法立即返回而不会阻塞）
            ChannelFuture channelFuture = bootstrap.connect(new InetSocketAddress(host, port)).sync();

            System.out.println("客户端开启!!!");

            //对关闭通道进行监听
            channelFuture.channel().closeFuture();

            //得到channel
            Channel channel = channelFuture.channel();
            //客户端需要输入信息，创建一个扫描器
            Scanner scanner = new Scanner(System.in);
            while (scanner.hasNextLine()) {
                String msg = scanner.nextLine();
                //通过channel 发送到服务器端
                channel.writeAndFlush(msg + "\r\n");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            eventLoopGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        new NettyClient("localhost", 10100).run();
    }
}
